package com.plant.es.test.client_version.handler.action;

import com.plant.es.test.client_version.handler.EsInterface;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;

/**
 * 4.查询
 * <p>
 * 在java rest client中调用elasticsearch中的数据，精准匹配的termQuery查不到数据，这个问题是java rest client客户端自带的bug，换用matchPhraseQuery直接替换即可。有点坑！
 * 在elastic权威指南一书中是这样给出建议的："匹配查询 match 是个 核心 查询。无论需要查询什么字段， match
 * 查询都应该会是首选的查询方式。它是一个高级 全文查询，这表示它既能处理全文字段，又能处理精确字段。"这就意味着match查询是高级查询，底层使用了term查询。
 * <p>
 * 结论：相关度查询使用match，精确字段查询使用matchPhrase即可。
 */
public class DocRelatedQuery implements EsInterface {
    @Override
    public void process(RestHighLevelClient esClient) throws IOException {
        //查询
        SearchRequest request = new SearchRequest();
        request.indices("user");

//        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
        //分页查询,条件查询
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 22));
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("name", "王五"));
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.from(0).size(2);
        //查询排序
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.sort("age", SortOrder.ASC);
        //过滤字段
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        String[] excludes = {};
//        String[] includes = {"age"};
//        builder.fetchSource(includes, excludes);
        //组合查询
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(QueryBuilders.matchQuery("age",23));    //and
//        boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男"));
//        boolQueryBuilder.should(QueryBuilders.matchQuery("age",23));  //or
//        boolQueryBuilder.should(QueryBuilders.matchQuery("sex","男"));
//        builder.query(boolQueryBuilder);
        //范围查询
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
//        rangeQuery.gte(23).lte(40);//大于等于23，小于等于40
//        builder.query(rangeQuery);
        //模糊查询，得要使用mapping给索引加分词器
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        FuzzyQueryBuilder fuzziness = QueryBuild
//        ers.fuzzyQuery("name", "王").fuzziness(Fuzziness.ZERO);//偏差距离Fuzziness.ONE：差一个匹配可以成功
//        builder.query(fuzziness);
        //高亮查询
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("name", "李四");
//        HighlightBuilder highlighter = new HighlightBuilder();
//        highlighter.preTags("<font color='red'>");
//        highlighter.postTags("</font>");
//        highlighter.field("name");
//        builder.highlighter(highlighter);
//        builder.query(matchPhraseQueryBuilder);
        //聚合查询
        SearchSourceBuilder builder = new SearchSourceBuilder();
//        AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");//aggregations:查询最大 age
        AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");//aggregations:根据 age 分组查询
        builder.aggregation(aggregationBuilder);

        request.source(builder);
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
}
